home *** CD-ROM | disk | FTP | other *** search
- name msxhpx
- ; File MSXHPX.ASM
- include mssdef.h
- ; Copyright (C) 1982,1991, Trustees of Columbia University in the
- ; City of New York. Permission is granted to any individual or
- ; institution to use, copy, or redistribute this software as long as
- ; it is not sold for profit and this copyright notice is retained.
- ; Edit history:
- ; 2 March 1991 version 3.10
- ; 2 Dec 2, 1990 Modify serhng so hangup works on serial port in connect mode.
- ; Nov. 24, 1990. Reemove reference to prserr to make link happy.
- ; Last edit Aug. 17, 1990
- ; August 9, 1990. Fix klogon and klogof.
- ; July 1990. Put in correct delay times for breaks. Thanks to Fred Lipschultz.
- ; June 1990. Install screen save for HP 110 and fixup dial command.[jan]
- ; February 1990. Major rewrite. Fix up for tektronix grapahics and 3.0.
- ; John Nyenhuis, Purdue EE 317-494-3524 nyenhuis@ecn.purdue.edu
- ; Binary works on both 110 and Plus.
- ; Change naming of ports to serial, modem, and 82164A
- ; Read keyboard less often and use BIOS screen write on plus for speed.
- ; 1 July 1988 Version 2.31
- ; 1 Jan 1988 version 2.30
- ; 25 May 1987 Add keyboard translator, input translation, cleanups. [jrd]
- ; 1 Oct 86 Version 2.29a
- ; 30 Sept 1986 Reject DEL char at serial port reception level to avoid
- ; problems when DEL is used as a filler char (by Emacs). [jrd]
- ; 28 Sept 1986 Revise procedure Term to permit capturing, printer ready
- ; testing, debug display. Revised other port procedures slightly too;
- ; especially to set port into binary mode via ioctl. [jrd]
- ; 22 Sept 1986 Add modifications from Mike Mellinger: outchr, serhng.
- ; Introduce COM3 as additional choice. Startup 8 bits, no parity. [jrd]
- ; 4 Sept 1986 Add Bob Goeke's change to move comms port table to a system
- ; dependent module (typ msx---) to allow 3+ ports and localized idents. [jrd]
-
- ; Date: 15 Oct 85
- ; HP Portable Kermit
- ; for HP110 and HP Portable Plus
- ; Port 1: Serial, Port 2: internal modem
- ; Defaults: even parity, 1200 baud: serial, 1200 internal modem
- ; Internal modem code only works on HP Portable Plus
- ; 15 Nov 85:
- ; Added code to shut off serial port and modem when quitting Kermit
- ; 11 Jan 86;
- ; change msdefs.h to mssdef.h for kermit 2.28 jrd
- ;
- ; Add global entry point vtstat for use by Status in mssset.
- ; Also trimmed off trailing commas in publics. Joe R. Doupnik 12 March 1986
- ; Add global procedures ihosts and ihostr to handle host initialization
- ; when packets are to be sent or received by us,resp. 24 March 1986
- ; Add global procedure dtrlow (without worker serhng) to force DTR & RTS low
- ; in support of Kermit command Hangup. Says Not Yet Implemented. [jrd]
- ; Add global procedure Dumpscr, called by Ter in file msster, to dump screen
- ; to a file. Just does a beep for now. 13 April 1986 [jrd]
- ; In proc Outchr add override of xon from chkxon sending routine.
- ; This makes a hand typed Xoff supress the xon flow control character sent
- ; automatically as the receiver buffer empties. 20 April 1986 [jrd]
- ; Fix port selector table, comptab, (from original version) to properly
- ; hold port name AUX. 23 April 1986 [jrd]
- ;
- ; Fixed error in resetting the serial port, 25 April 1986
- ;
- page 80,132
-
-
- ; mov a string all registers preserved
- movsmac macro xsource, xdestination, xlength
- push cx
- push di
- push si
- mov si,offset xsource
- mov di, offset xdestination
- mov cx,xlength
- cld ; move forward
- rep movsb ; do the move
- pop si
- pop di
- pop cx
- endm
- writechar macro saying
- push dx
- push ax
- mov ah,2
- mov dl,saying
- int dos
- pop ax
- pop dx
- endm
-
- writestring macro saying
- push ax
- push dx
- mov ah,prstr
- mov dx,offset saying
- int dos
- pop dx
- pop ax
- endm
-
- saveregs macro
- pushf
- push ax
- push bx
- push cx
- push dx
- push es
- push di
- push si
- push ds
- push bp
- endm
-
- restoreregs macro
- pop bp
- pop ds
- pop si
- pop di
- pop es
- pop dx
- pop cx
- pop bx
- pop ax
- popf
- endm
-
- mul10 macro register ; multiply register other then ax by 10
- push ax
- mov ax,register
- mov temp1,ax
- shl ax,1
- shl ax,1
- shl ax,1
- add ax,temp1
- add ax,temp1
- mov temp1,ax
- pop ax
- mov register,temp1
- endm
-
- delay macro number
- push ax
- push cx
- mov ax,number
- call pcwait
- pop cx
- pop ax
- endm
-
-
- ; structure for status information table sttab.
- stent struc
- sttyp dw ? ; type (actually routine to call)
- msg dw ? ; message to print
- val2 dw ? ; needed value: another message, or tbl addr
- tstcel dw ? ; address of cell to test, in data segment
- basval dw 0 ; base value, if non-zero
- stent ends
-
-
-
- ;; below 40 publics are the minimum necessary
- public baudst,ihostr,bdtab,getbaud,chrout
- public pcwait,putmod,serrst,trnprs,prtchr
- public poscur,outchr,dtrlow,vts,puthlp
- public vtstat,coms,cquery,ctlu,shomodem
- public portval,getmodem,term,dumpscr,cmblnk
- public cquit,locate,clearl,machnam,lclini
- public sendbl,comptab,sendbr,clrmod,cstatus
- public termtb,serhng,clrbuf,beep, serini
- ;;additional system dependent publics
- public klogon,kdos,snull,klogof
- public bigscreen ; bigscreen=1 if it's big [jan]
- public termtog ; toggle terminal types [jan]
- public kclrscn, ourhelp, getflgs, dial_number, sethpkey, setaltkey
- public setkeyboard, vtstbl, setchtab
-
- false equ 0
- true equ 1
- instat equ 6
- print_out equ 05h ; dos function to print to printer
- prtscr equ 80h ; print screen pressed
- hpkeynum equ 11
- altkeynum equ 12
- tekonnum equ 13
- tekoffnum equ 14
-
- data segment public 'data'
- extrn flags:byte, trans:byte
- extrn dmpname:byte
- extrn kbdflg:byte, rxtable:byte
- extrn lclexit:word ; call when quitting kermit
- extrn lclsusp:word ; call when pushing to dos
- extrn lclrest:word ; call when exiting from dos
- extrn tekflg:byte,denyflg:word
- extrn dosnum:word
- extrn repflg:byte, diskio:byte ; for replay feature
- extrn kbdflg:byte ; in telnet
-
- ; hp110/ portable plus specific
- machnam db 'Can Not Identify Terminal ','$' ; should never see this
- hp110_name db 'HP_110$'
- lenhp110_name equ $-hp110_name
- plus_name db 'HP_Portable_Plus$'
- lenplus_name equ $-plus_name
-
- ; num_rows and bigscreen must be set by lclini everything else is
- ; determined by the program
- ;; everybody defaults to 110
- num_rows dw 16 ; default
- bigscreen db 1 ; 1 for plus 0 for 110
- graph_bytes dw 25*60*8 ; size of graphics screen
-
- erms20 db cr,lf,'?Warning: System has no disk drives$'
- erms40 db cr,lf,'?Warning: Unrecognized baud rate$'
- erms41 db cr,lf,'?Warning: Cannot open com port$'
- erms50 db cr,lf,'Error reading from device$'
- serierr db cr,lf,'Can not initialize port $'
- write2err db cr,lf,'Can not write to com port $'
- badbd db cr,lf,'Unimplemented baud rate$'
- badpar db cr,lf,'Unimplemented parity$'
- noimp db cr,lf,'Command not implemented.$'
- hngmsg db cr,lf,' The phone should have hungup.',cr,lf,'$'
- hnghlp db cr,lf,' The modem control lines DTR and RTS for the current'
- db ' port are forced low (off)'
- db cr,lf,' to hangup the phone. Normally, Kermit leaves them'
- db ' high (on) when it exits.'
- db cr,lf,'$'
- msmsg1 db cr,lf,' Communications port is not ready.$'
- msmsg2 db cr,lf,' Communications port is ready.$'
- rdbuf db 80 dup (?) ; temp buf
- shkmsg db 'Not implemented.'
- shklen equ $-shkmsg
- baudstr db 'SB' ; string used in setting baud rate
- baudx db 0,';' ,'$'
- flo_str db 'C' ; string used to set flow
- flo_x db '0',';','$' ; 0=no flow 2=xon/xoff
- brk_on db 'B1;' ; start sending breaks
- brk_off db 'B0;' ; stop sending breaks
- chk_msg db 0BFH,';' ; check serial buffer
- ask_cursor db escape,'[6n','$'
- badcursor db 'Unable to get cursor position ',cr,lf,'$'
- ask_modem_status db 'MS;'
- transmiton db 'Transmit On ',cr,lf,'$'
- offhook db 'Modem is off hook ',cr,lf,'$'
- modemenabled db 'Modem is Enabled ',cr,lf,'$'
- dial_msg db 'MR;'
- $m0 db 'M0;SW0;P4;SS0;LI1;'
- len_$m0 equ $-$m0
- $m1 db 'M1;SW0;P4;SS0;LI1;'
- len_$m1 equ $-$m1
- $off_m db 'C2;P0;SS0;SW1;M3;M5;' ; turn off portable plus
- off_len equ $-$off_m
- $off_m110 db 'C2;P0;SS0;SW1;MH;' ; string to turn off 110 modem
- len$off_m110 equ $-$off_m110
- need_to_set_baud db true ; only set baud when needed
- ;;need_to_set_flow db true ; need to update flow control
- ;
- setktab db 0
- setkhlp db 0
- crlf db cr,lf,'$'
- delstr db BS,escape,'P','$'
- clrlin db cr,ESCAPE,'K$'
- clreol db ESCAPE,'K$'
- hpkey db escape,'&k0\$' ; hp keyboard
- altkey db escape,'&k1\$' ; alternate keyboard
- tekstatustxt db 'Tek Auto Entry: $'
- tekbyte db tekonnum
- keystatustxt db 'Keyboard: $'
- keyflg db altkeynum
- ; escape sequences for turning on the alpha display
- ; on the 110, we also need to load the character set
- ; id_terminal will decide which one to use
-
- alpha_disp db escape,'[=8h',escape,'[10m','$','xxxxxxxxxxx','$' ; default
- alpha_110 db escape,'[=8h',escape,'[10m','$' ; for 110
- lenalpha_110 equ $-alpha_110 ; Its length
- alpha_plus db escape,'[=8h',escape,'*dK','$' ; for plus
- lenalpha_plus equ $-alpha_plus ; Its length
- cursav db escape,'[s','$' ; save the cursor
- curres db escape,'[u','$' ; restore cursor
- curon db escape,'*dQ','$' ; turn on cursor
- curoff db escape,'*dR','$' ; turn off the cursor
- old_cursor dw ? ; store alpha cursor position
- transfcn db escape,'&s0A$' ; transmit functions,
- dialcode db 32 ; 16 for pulse 32 for tone
- termidfail db escape,'Kermit can not identify terminal type ',cr,lf,'$'
- ask_id db escape,'*s^','$' ; is it 110 or plus
- dial_saying db 'Enter Number to dial ,=delay ;=cancel P=pulse T=tone.',cr,lf,'$'
-
- rdbuffstrt dw ? ; start of rdbuff for dial_number
- canceldial db 'Dial Cancelled ',cr,lf,'$'
- modem_saying db 'Set port to internal modem before dialing ',cr,lf,'$'
- onhook_saying db 'Modem is already connected ',cr,lf,'$'
- w_ioctlerr db cr,lf,'Error in writing to ioctl ',7,'$'
- r_ioctlerr db cr,lf,'Error in reading ioctl ',7,'$'
- io_notready db cr,lf,'Not ready to write to ioctl ','$'
- helpini db cr,lf,'Press Extended f1 for help in connect mode ',cr,lf,'$'
- ourhelptxt db cr,lf ,'Some Special Keys in Connect Mode: '
- db cr,lf,'Menu clears screen'
- db cr,lf,'User System toggles between alpha and tektronix screens. '
- db cr,lf,'Extended B sends a break ','$'
- helpplus db cr,lf, 'Extended = also clears the screen '
- db cr,lf,'Extended - also toggles between alpha and tektronix screens','$'
- help110 db cr,lf, 'Press Extended D to dial a number ','$'
- helpend db cr,lf,cr,lf,'Press any key to return to connect mode','$'
- telflg db 0 ; non-zero if we're a terminal
- xofsnt db 0 ; Say if we sent an XOFF
- xofrcv db 0 ; Say if we received an XOFF
- invseq db ESCAPE,'&dB$' ; Reverse video
- nrmseq db ESCAPE,'&d@$' ; Normal video
- ivlseq db 80 dup (' '),cr,'$' ; make line inverse video
- prthnd dw 0 ; Port handle
- argadr dw ? ; address of arg blk from msster.asm
- parmsk db ? ; 8/7 bit parity mask, for reception
- flowoff db ? ; flow-off char, Xoff or null (if no flow)
- flowon db ? ; flow-on char, Xon or null
- captrtn dw ? ; routine to call for captured output
- tempbuf dw 10 dup(?)
- prttab dw com1,com2,com3
- com1 db 'COM1',0
- com2 db 'COM1',0 ; this gets changed on plus
- com3 db 'COM2',0
- blank db ESCAPE,'H',ESCAPE,'J$'
- movcur db ESCAPE,'&a'
- colno db 20 dup(?)
- ten db 10
- temp dw 0
- temp1 dw 0 ; Temporary storage
- temp2 dw 0 ; Temporary storage
- tempbyte db 0
-
- ;;new stuff to scan escape sequences from comm port [jan]
- stringtab dw tekst1,tekst2 ; strings for matching
- dw badst1,badst2
- numstrings equ 4 ; number of strings to match
- disptab dw toteknoplay,totekplay ; dispatch table
- dw ignoreall, ignoreall
- tekst1 db escape,'[?38h',0 ;1st string to get into tek mode [jan]
- tekst2 db escape,FF,0 ;2nd string to get into tek mode [jan]
-
- badst1 db escape,'[=8h',0 ; ignore alpha on sequence
- badst2 db escape,'[=10h',0 ; ignore graph on sequence
-
- stringchekbuff db 16 dup (0)
- stringchekcnt dw 0 ;characters already in buffer
- matchsofar dw false ; no match yet
- match dw 0
- playem db false ;don't play back switch characters
- ; end of data for string scannine
- prtrdy db true ; if false, we get out of connect mode
-
- keydelay dw 0
-
- scrsavseg dw ? ; segment of screen memory
- line_len dw ? ; words in a line
- line_ofs dw ? ; ofset between adjacent lines
- num_lines dw ? ; number of lines in screen memory
-
- ints_set db false ; interrupts vectors set?
- need_break db false
- brk_int equ 58h ; break key interrupt
- savbrko dw ? ; save offset of break interrupt
- savbrks dw ? ; save segment of break interrupt
-
- vtstbl stent <srchkw,keystatustxt,termtb,keyflg> ; tell keyboard for status
- stent <srchkw,tekstatustxt,termtb,tekbyte> ; tell keyboard for status
- dw 0 ; end of table
-
- ; Entries for choosing communications port. [19b]
- comptab db 3 ; 7 entries. Rewritten by [jrd]
- mkeyw 'Serial',1
- mkeyw 'Modem',2
- mkeyw '82164A',3 ; 3 is hpil
-
- setchtab db 1 ; set file character-set table
- mkeyw 'CP437',437
-
- termtb db 6
- mkeyw 'HP2621',ttgenrc
- mkeyw 'Tek4010',tttek
- mkeyw 'HpKeyBoard',hpkeynum
- mkeyw 'AltKeyBoard',altkeynum
- mkeyw 'EnableTek', tekonnum
- mkeyw 'DisableTek',tekoffnum
-
- defbaud equ 7 ; default baud rate
- port1 prtinfo <defbaud,0,defpar,1,0,defhand,floxon,0>
- port2 prtinfo <defbaud,0,defpar,1,0,defhand,floxon,0>
- port3 prtinfo <defbaud,0,defpar,1,0,defhand,floxon,0>
- portval dw port2 ; Default is to use port 1
-
- bdtab db 15 ; Baud rate table
-
- mkeyw '50',0
- mkeyw '75',1
- mkeyw '110',2
- mkeyw '134',3
- mkeyw '150',4
- mkeyw '300',5
- mkeyw '600',6
- mkeyw '1200',7
- mkeyw '1800',8
- mkeyw '2400',9
- mkeyw '3600',10
- mkeyw '4800',11
- mkeyw '7200',12
- mkeyw '9600',13
- mkeyw '19200',14
- ourbdtab db '1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
-
- ; variables for serial interupt handler
-
- source db 260 DUP(?) ; buffer for data from port
- bufout dw 0 ; buffer removal pointer
- count dw 0 ; number of chars in int buffer
- bufin dw 0 ; buffer insertion pointer
- ; variable for fast write on plus
- plus_char db 'R',0
-
- ourarg termarg <>
- asciitab db '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
-
-
- data ends
-
- code segment public 'code'
- extrn comnd:near, dopar:near, atoi:near, prompt:near
- extrn sleep:near
- extrn tekcls:near
- extrn msuinit:near, keybd:near ; in msuhpx
- extrn tekemu:near,tekini:near
- extrn sbrk:near ; memory allocator
- extrn statc:near, srchkw:near
-
- assume cs:code,ds:data,es:data
-
- ;check string to see if we need to do something special
-
- stringchek proc near
- cmp stringchekcnt,0 ; nobody in yet?
- jne stringchek1 ; ne => already have characters
- cmp al,escape ; is this escape?
- je stringchek1 ; it is escape, so go and process
- cmp al,escape+80h ; in case parity is odd
- je stringchek1 ; process escape
- stc ; display the character
- ret ; return quickly if nothing to do
- stringchek1: ; here is escape already in
- saveregs
- and al,07fh ;strip high bit
- mov bx,stringchekcnt
- mov stringchekbuff[bx],al ;put character in buffer
- inc stringchekcnt ;one more character in buffer
- call stringtest ; does the string in stringchekbuff match?
- cmp match,0 ; 0 means no match
- je stringchek2
- mov si,match ; here means we have a match
- shl si,1 ; multiply by 2
- dec si
- dec si ; 1=0, 2=1 etc
- call disptab[si] ; call appropriate function
- call stringbuffplay ; play back the buffer
- clc ; don't display
- jmp stringchek3 ; return and don't display character
- stringchek2:
- clc ; don not display
- cmp matchsofar,true ; do we have a match so far
- je stringchek3 ; e=true , get out
- mov playem,true
- call stringbuffplay ; clean out the buffer
- clc ; don't display character
- stringchek3:
- restoreregs
- ret
- stringchek endp
-
- ;test to see if input string is a match to toggle terminal [jan]
-
-
- ; stringtab gives addresses of 0 terminated strings
- ; teststring in stringchekbuff
- ;numstrings is the number to checked
- ; matchsofar will have be true if there is a possilbe match
- ; match will be non-zero 1, 2, 3 indicating number of match if a match
- ; if no match yet, match will be 0
- ; severaal registers get destroyed
- stringtest proc near
- mov matchsofar, false ; assume no match
- mov match,0 ; no match
- xor si,si ; pointer to string tab
- dec si
- dec si ; step back 1 item
- mov cx,0 ; cx points to number of string
- strtst1:
- inc cx ; strings number
- cmp cx,numstrings ; done parsing table?
- ja strtst5 ; we're done, get out of here
- mov di, offset stringchekbuff
- inc si
- inc si ; point to next item
- mov bx,stringtab[si] ; offset of string
- strtst2:
- mov al,[di] ; stringchekbuff in al
- mov ah,[bx] ; string element to test in ah
- cmp al,0 ; end of stringchekbuff
- jne strtst2a ; ne=> not at end of buffer
- mov matchsofar,true ; we have a match so far
- jmp strtst5 ; return to caller
- strtst2a:
- cmp ah,0 ; at end of string?
- je strtst1 ; failure, go to next string
- cmp ah,al ; match?
- jne strtst1 ; no match, on to next string
- ; here if match
- mov ah,[bx+1] ; next byte from string
- cmp ah,0 ; are we done with string?
- je strtst3 ; e => yes, a match
- inc bx ; next element in string
- inc di ; next character in stringchekbuff
- jmp strtst2 ; check next item in string
- strtst3: ; here if we have a match
- mov match,cx ;
- mov matchsofar,true ;
- strtst5:
- ret
- stringtest endp
-
-
-
- ;play back characters in string buffer ..called by stringchek
- stringbuffplay proc near
- xor bx,bx ;bx=0
- mov cx,stringchekcnt
- stringbuffplay1:
- mov al,stringchekbuff[bx]
- cmp playem,true ;playback characters?
- jne stringbuffplay2 ;ne = no don't play back
- push bx ; save index
- push cx ; save count
- call outtty ; print the character
- pop cx ; restore count
- pop bx ; restore index
- stringbuffplay2:
- mov stringchekbuff[bx],0 ;set to 0
- inc bx ;point to next character
- loop stringbuffplay1 ;repeat until buffer is empty
- mov stringchekcnt,0 ;now no characters in buffer
- ret
- stringbuffplay endp
-
- ignoretek proc near ; ignore this escape sequence in tek mode
- mov playem,false
- cmp flags.vtflg,tttek ; are in in tek emulation
- je ignoretek1 ; e=yes do not play back
- mov playem,true
- ignoretek1:
- ret
- ignoretek endp
-
- ignoreall proc near ; always ignore this escape sequence
- mov playem,false
- writechar bell
- ret
- ignoreall endp
-
- totekplay proc near ; turn on tektronix
- mov playem,true ; play back characters
- jmp totek
- totekplay endp
-
- toteknoplay proc near
- mov playem,false
- jmp totek
- toteknoplay endp
-
-
- totek proc near ; turn on tektronix
- test denyflg,tekxflg ;tek auto entry enabled?
- jz totek1
- mov playem,true ; play back characters
- ret
- totek1:
-
- cmp flags.vtflg,tttek ; already doing tek
- je totek2
- call termtog ; toggle to tektronix
- totek2:
- ret
- totek endp
-
-
- setkeyboard proc near ; set appropriate keyboard
- cmp keyflg,altkeynum ; want alternate keyboard
- je setkbd1 ; e=> set altkeyboard
- call sethpkey
- ret
- setkbd1:call setaltkey
- ret
- setkeyboard endp
-
- sethpkey proc near
- writestring hpkey
- ret
- sethpkey endp
-
- setaltkey proc near
- writestring altkey
- ret
- setaltkey endp
-
- scrsavinit proc near ; set up memory block to save screen memory [jan]
- saveregs
- mov ax,num_rows
-
- mov cl,9
- shl ax,cl
- mov bx,ax ; bx=512*num_rows
- mov ax,num_rows
- mov cl,7
- shl ax,cl ; ax=128*num_rows
- add ax, bx ; ax=640*numrows
- mov cx,ax ; save num bytes in cx
- push cx
- call sbrk ; memory manager
- pop cx ; recover number of bytes
- shr cx,1 ; cx has number of words
- mov scrsavseg,ax ; save it
- xor ax,ax
- mov di,ax
- mov es,scrsavseg
- rep stosw
- restoreregs
- clc
- ret
- scrsavinit endp
-
- savescr proc near ; save dislply memory
- saveregs ; save the registers
- mov di,0 ; tek page by default
- mov line_len,60 ; bytes in tek line
- mov line_ofs,64 ; bytes between adjacent tek lines
- mov ax, num_rows ; number of rows
- shl ax,1 ; each row has 8 lines
- shl ax,1 ; so multipy by 8
- shl ax,1
- mov num_lines,ax
- xor si,si ; tek display starts at 8000:0000
- xor dx,dx ; dx points to offset of current line
- cmp flags.vtflg,tttek ; doing tek emulation?
-
- je savesc1 ; je means yes we are doing tek
- cmp bigscreen,0 ; don't save for 110
- jne savesca ; ne=> we have a plus
- ;; here if saving for hp110
- mov di,graph_bytes ; here if saving 110 screen
- mov line_len,128 ; each line is 128 bytes
- mov line_ofs, 128 ; lines offset by 128 bytes
- call askcursor ; cursor location in dx
- mov old_cursor,dx ; save old cursora
- writestring curoff ; turn off the cursor
- in al,0e6h ; get row number at display top
- and al,63 ; insurance
- xor ah,ah
- mov cl,7
- shl ax,cl
- mov dx,ax
- mov si,dx
- mov ax,num_rows
- mov num_lines,ax
- jmp savesc1 ; do the save
- savesca:
- mov di,graph_bytes ; here if saving alpha screen
- mov line_len,160 ; bytes in alpha line
- mov line_ofs,256 ; bytes between adjacent alpha lines
- call askcursor ; cursor location in dx
- mov old_cursor,dx ; save old cursora
- writestring curoff ; turn off the cursor
- in al,83h ; get row number of display top
- mov ah,al ; multiply by 256 to get byte number
- xor al,al
- mov dx,ax ; offset of alpha display start in dx
- mov si,dx
- mov ax,num_rows
- mov num_lines,ax ; each row is one line in alpha
- savesc1:
- mov ax,scrsavseg ; screen save segment
- mov es,ax
- mov cx,num_lines
- savesc2:
- push cx ; save number of lines
- mov cx,line_len
- shr cx,1 ; words = bytes/2
- mov ax,8000h ; screen memory segment
- push ds
- mov ds,ax
- cld
- rep movsw ; move line
- pop ds ; get back kermit's ds
- pop cx ; get back line number
- add dx,line_ofs ; point to beginning of next line
- ; check for wrap on hp110
- cmp bigscreen,1 ; is it a plus?
- je savesc2a ; = means yes, it is a plus
- cmp flags.vtflg,tttek ; tek emulation?
- je savesc2a ; e=> yes, don't worry about wrap
- cmp dx,128*48 ; ready to wrap around on hp110?
- jb savesc2a ; ne=> not there yet
- mov dx,0 ; point to first line on hp110 display
- ; end of wrap check on hp110
- savesc2a:
- mov si,dx
- loop savesc2 ; do the next line
- cmp flags.vtflg,tttek ; doing tek emulation
- je savesc3 ; yes, don't turn on cursor
-
- writestring curon ; turn on the cursor
- savesc3:
- savescrex:
- restoreregs ; restore the registers
- clc ; all ok
- ret
- savescr endp
-
-
- restscr proc near ; move ds:si(memory) to es:di (screen)
- saveregs ; save the registers
- mov si,0 ; tek page by default
- mov line_len,60 ; bytes in tek line
- mov line_ofs,64 ; bytes between adjacent tek lines
- mov ax, num_rows ; number of rows
- shl ax,1 ; each row has 8 lines
- shl ax,1 ; so multipy by 8
- shl ax,1
- mov num_lines,ax
- xor di,di ; tek starts at 8000:0000
- xor dx,dx ; dx points to offset of current line
- cmp flags.vtflg,tttek ; doing tek emulation?
- je restsc1 ; je means yes we are doing tek
- writestring alpha_disp ; reload the hp character set
- cmp bigscreen,0 ; using the 110 ?
- jne restsca ; ne=> we have the plus
- call cmblnk ; blank display on 110
- writestring curoff ; turn off the cursor
-
- mov si,graph_bytes ; here if restoring alpha screen
- mov line_len,128 ; bytes in alpha line
- mov line_ofs,128 ; bytes between adjacent alpha lines
- in al,0e6h ; get row number of display top
- and al,63 ; insurance
- mov cl,7 ; multiply by 128 to get byte number
- xor ah,ah
- shl ax,cl
- mov dx,ax ; dx points to start of line
- mov di,dx ; offset of alpha display start
- mov ax,num_rows
- mov num_lines,ax
- jmp restsc1
-
- restsca:
- call cmblnk ; blank display
- writestring curoff ; turn off the cursor
-
- mov si,graph_bytes ; here if restoring alpha screen
- mov line_len,160 ; bytes in alpha line
- mov line_ofs,256 ; bytes between adjacent alpha lines
- in al,83h ; get row number of display top
- mov ah,al ; multiply by 256 to get byte number
- xor al,al
- mov di,ax ; offset of alpha display start
- mov dx,di ; dx points to start of line
- mov ax,num_rows
- mov num_lines,ax
- restsc1:
- mov cx,num_lines
- restsc2:
- push cx ; save number of lines
- mov cx,line_len
- shr cx,1 ; words = bytes/2
- mov ax,8000h ; screen memory segment
- mov es,ax ; es:di points to display memory
- cld
- mov ax,scrsavseg ;
- push ds ; save kermit's ds
- mov ds,ax ; ds points to screen save memory
- rep movsw ; move line
- pop ds ; get back kermit's ds
- pop cx ; get back line number
- add dx,line_ofs ; dx points to begin of next lien
- mov di,dx ; point to next line in desplay
- ; check for wrap around on hp110
- cmp bigscreen,1 ; using a plus
- je restsc2a ; e=> yes its a plus
- cmp flags.vtflg,tttek ; doing tek
- je restsc2a ; e=> yes, dont worry about 110 wrap
- cmp dx,48*128 ; need to wrap
- jb restsc2a ; ne=> no
- mov dx,0
- mov di,dx
- ; end of wrap around check on hp110
- restsc2a:
- loop restsc2 ; do the next line
- cmp flags.vtflg,tttek ; doing tek emulation
- je restsc3 ; yes, skip the cursor stuff
-
- mov dx,old_cursor
- call poscur
- writestring curon ; turn on the cursor
- restsc3:
- restscrex:
- restoreregs ; restore the registers
- clc ; all ok
- ret
- restscr endp
-
- ; identify wether we have hp110 or portable plus
- ; if plus then bigscreen = 1 else bigscreen =0
- id_terminal proc near
- saveregs
- call clear_key_buffer ; clear the keyboard buffer if needed
- writestring ask_id ; ansi termial ask string
- push ds
- pop es ; es=ds for string moves
- call getkey ; first key in string is 1 or 4
- cmp al,'1' ; 1 for hp110
- jne id_ter2 ; ne means its a plus
- mov bigscreen,0
- mov num_rows,16 ; it's a 110
- mov graph_bytes,16*60*8 ; bytes in graphics screen
- movsmac hp110_name, machnam, lenhp110_name ; move name
- movsmac alpha_110, alpha_disp, lenalpha_110 ; mov alpha message
- jmp id_ter4 ; normal exit
- id_ter2: mov bigscreen,1 ; its a plus
- mov num_rows,25
- mov graph_bytes,25*60*8 ; bytes in graphics screen
- movsmac plus_name machnam lenplus_name ; move machine name
- movsmac alpha_plus alpha_disp lenalpha_plus ; alpha message
- mov bx,offset com2
- mov al,'3'
- mov [bx+3],al ; com2 is always modem
- jmp id_ter4 ; normal exit
- id_tererr: writestring termidfail
- id_ter4: call clear_key_buffer
- restoreregs
- clc
- ret
- id_terminal endp
-
- modem_status_byte proc near ; get status byte on 110
- cmp bigscreen,0 ; is this a 110
- je modembyte1 ; => yes it is
- mov al,0 ; no status on plus
- ret
- modembyte1:
- saveregs
- mov dx, offset ask_modem_status
- mov cx,3 ; 3 bytes
- call w_ioctl ; ask the status
- mov cx,1 ; 1 byte to read
- call r_ioctl
- restoreregs
- mov ax, tempbuf ; retrive the status byte
- clc
- ret
- modem_status_byte endp
-
- modem_status proc near ; get modem status
- saveregs
- call modem_status_byte ; al will contain status
- test al,2 ; transmit enabled
- jz modem_stat1
- writestring transmiton
- modem_stat1:
- test al,8 ; is modem off hook?
- jz modem_stat2
- writestring offhook
- modem_stat2:
- test al,128 ; is the modem enabled?
- jz modem_stat3
- writestring modemenabled
- modem_stat3:
- restoreregs
- clc
- ret
- modem_status endp
-
- dial_number proc near ; dial a number
- cmp bigscreen,0 ; is this a 110?
- je dial_numa ; e=> yes, do the dial
- ;; ret ; don't do anything if its a plus
- dial_numa: ; start code which runs only on 110
- saveregs
- call savescr
- writestring alpha_disp
- ;; call cmblnk ; give a nice screen to work with
-
- cmp flags.comflg,2 ; using port 2?
- je dial_num0 ; e => yes, we are
-
- writestring modem_saying ;
- mov ax,500 ; wait a second
- call pcwait
- jmp dial_ex ; can't dial until port set right
- dial_num0:
- call modem_status_byte
- test al,128 ; is the modem on?
- jz dial_num1 ; it's not on so ok to dial
- writestring onhook_saying ; tell user he can't dial with modem on
- mov ax,500
- call pcwait
- jmp dial_ex
- dial_num1:
- call modem_status
- mov ax,offset rdbuf ; rdbuf is work buffer
- push ds
- pop es ; es points to data segment
- mov di,ax ; let rdbuf be our buffer
- call clear_key_buffer
- writestring dial_saying
- mov al,'M'
- mov [di],al
- inc di
- mov al,'D'
- mov [di],al
- inc di
- mov rdbuffstrt,di ; the start location of new characters
- mov dl,16 ; tone dial is default
- dial_num2:
- call getkey ; get key from user
- cmp al,8 ; backspace?
- je dial_num2b ; backspace, so erase previous char.
- cmp al,127 ; delete is also legal backspace
- jne dial_num2c ; ne => no backspace
- ; here to handle backspace
- dial_num2b:
- cmp di,rdbuffstrt ; any characters in the command buffer?
- je dial_num2 ; nobody in yet, so do nothing
- call dodel ; write a backspace
- dec di ; remove last character from buffer
- jmp dial_num2 ; get the next character
- ; end of backspace handler
- dial_num2c:
- ;; writechar al ; display for user
- cmp al,cr ; are we done
- je dial_num8
- cmp al,';' ; ':' cancels dial command
- je dial_num2c1
- cmp al,3 ; control c cancels
- je dial_num2c1
- cmp al,escape ; escape also cancels
- je dial_num2c1
- jmp dial_num2d ; continue
- dial_num2c1: jmp dial_ex ; cancel dial command
- dial_num2d:
- cmp al,',' ; pause command
- jne dial_num2e
- writechar al ; write comma to screen
- mov al,2 ; 2 second delay
- mov [di],al
- inc di ; point to next byte in rdbuf
- jmp dial_num2
- dial_num2e:
- cmp al,'p' ; pulse?
- jne dial_num3
- mov dl,32
- dial_num3: cmp al,'P' ; pulse ?
- jne dial_num4
- mov dl,32
- dial_num4: cmp al,'t' ; tone?
- jne dial_num5
- mov dl,16
- dial_num5: cmp al,'T' ; again tone
- jne dial_num6
- mov dl,16
- dial_num6: cmp al,'0'
- jb dial_num2 ; ignore this one
- cmp al,'9' ; is it too big
- ja dial_num2 ; yes, too big, so ignore
- writechar al ; write it on screen
- sub al,'0' ; convert ascii to binary
- add al,dl ; add dial code
- mov [di],al ; put in the read buffer
- inc di ; next byte in readbuffer
- jmp dial_num2 ; get next key from user
- dial_num8:
- mov al,2 ; 2 second delay
- mov [di],al
- inc di
- mov al,80 ; enable transmit tone
- mov [di],al
- inc di
- mov al,64 ; enable originate mode
- mov [di],al
- inc di
- mov al,255 ; terminate dial sequence
- mov [di],al
- inc di
- mov al,';' ; add semicolon
- mov [di],al
- inc di
- mov al,' ' ; finish with a blank
- mov [di],al
- inc di
- mov al,'$'
- mov [di],al
- ;; writestring rdbuf
-
- ;; now dial string is safely in rdbuf and size in dh
- mov cx,di
- mov ax,offset rdbuf ; start of string
- sub cx,ax ; cx has bytes in buffer
- push cx ; save the number to write
- mov dx, offset dial_msg
- mov cx,3
- call w_ioctl ; tell pc we want to dial a number
- mov ax,50 ; wait to let things settle
- call pcwait ; wait 50 ms
- mov dx,offset rdbuf
- pop cx ; number of byres
- call w_ioctl
- call modem_status ; tell user the status
-
- jmp dial_ok ; all ok
- dial_ex: writestring canceldial
- dial_ok:
-
- mov ax,1000 ; give user time to read message
- call pcwait ; wait a short while
- cmp flags.vtflg,tttek ; doing tek
- jne dial_tog
- call tekini ; need to reinitialize emulator
- dial_tog:
- call restscr
- restoreregs
- clc ; stay in connect
- ret
- dial_number endp
-
-
-
- askcursor proc near ; return curor row in dh, column in dl
- mov dx,257 ; default
- saveregs
- call clear_key_buffer ;
- writestring ask_cursor ; ansi ask cursor message
- mov ax,50
- call pcwait ; wait a whill
- xor cx,cx
- askcur1:
- call getkey
- inc cx
- cmp cx,20
- ja askcurex
- cmp al,'['
- jne askcur1
- xor bx,bx ; keep row number in bx
-
- askcur2:
- call getkey
- cmp al,';' ; this signifies start of column report
- je askcur3
- sub al,'0' ; make binary
- mul10 bx ; multiply by 10
- add bl,al
- inc cx
- cmp cx,20
- ja askcurex
- jmp askcur2 ; repeat until done
-
- askcur3: mov dh,bl ; row in dh
- xor bx,bx ; now get column
- askcur4: call getkey
- cmp al,'R' ; this signifies start of column report
- je askcur5
- sub al,'0' ; make binary
- mul10 bx ; multiply by 10
- add bl,al
- inc cx
- cmp cx,20
- ja askcurex
- jmp askcur4 ; repeat until done
- askcur5: mov dl,bl ; column in dl
- jmp askcur7
- askcurex: writestring badcursor
- askcur7: clc
- mov temp1,dx
- restoreregs
- mov dx,temp1
- dec dh ; map (1,1) to (0,0)
- dec dl
- ret
- askcursor endp
-
-
- getkey proc near ; wait for a key to be typed
- mov ah,7
- int dos
- ret
- getkey endp
-
- clear_key_buffer proc near
- saveregs
- clear_key1:
- mov ax,0600h
- mov dx,0ffffh
- int dos
- jnz clear_key1
- restoreregs
- clc
- ret
- clear_key_buffer endp
-
- ourhelp proc near ; give user some help
- saveregs
- call savescr ; save current screen
- writestring alpha_disp; be sure alpha is on
- call cmblnk ; blank the screen
- writestring ourhelptxt
- cmp bigscreen,1 ; do we have a plus ?
- je ourhelp1
- writestring help110
- jmp ourhelp2
- ourhelp1: writestring helpplus
- ourhelp2: writestring helpend
- call getkey ; user types a key when done reading
- cmp flags.vtflg,tttek ; doing tek emulation
- jne ourhelp3 ; ne => we're doing alpha screen
- call tekini ; need to reinitialize the emulator
- ourhelp3:
- call restscr ; give him back his previous screen
- restoreregs
- clc ; stat in connect mode
- ret
- ourhelp endp
-
- getrepchr proc near ; get replay character for file
- mov ah,readf2 ; read from replay file
- mov bx,diskio.handle
- mov cx,1 ; read 1 character
- mov dx,offset rdbuf ; to this buffer
- int dos
- jc getrepchr1 ; c => failure
- cmp ax,cx ; read the byte?
- jne getrepchr1
- mov al,rdbuf ; al has character
- clc ; character available in al
- ret
-
-
- getrepchr1:
- call beep ; announce file is done
- call beep
- call getkey ; wait for a key to be pressed
- mov prtrdy,false ; so we exit connect mode
- stc
- ret ; no character available
- getrepchr endp
-
- repchrout proc near ; process key in al while replaying
- and al,7fh ; strip parity
- repchrout1:
- cmp al,'C'-40h ; Control C?(to exit playback mode)
- je repchrout3 ; e=> yes, return failure
- cmp al,XOFF ; user wants to stop?
- jne repchrout2 ; ne => ok to continue
- call getkey ; wait and get a key
- jmp repchrout1 ; now process this key
- repchrout2:
- clc ; return success
- ret
- repchrout3:
- mov prtrdy,false ; exit terminal
- stc ; exit connect mode
- ret
- repchrout endp
-
-
- ; Clear the input buffer. This throws away all the characters in the
- ; serial interrupt buffer. This is particularly important when
- ; talking to servers, since NAKs can accumulate in the buffer.
- ; Returns normally.
-
- CLRBUF PROC NEAR
- cmp repflg,0 ; don't clear if replaying
- je clrbuf0
- ret
- clrbuf0:
- push ax ; necessary for msghpx
- mov bufin,offset source
- mov bufout,offset source
- mov count,0
- clrbuf1: call prtchr ; empty out firmware buffer
- jnc clrbuf1
- pop ax
- ret
- CLRBUF ENDP
-
- ; Clear to the end of the current line. Returns normally.
-
- CLEARL PROC NEAR
- push ax ; save regs
- push dx
- mov ah,prstr
- mov dx,offset clreol
- int dos
- pop dx
- pop ax
- ret
- CLEARL ENDP
- ; Put the char in AH to the serial port. This assumes the
- ; port has been initialized. Should honor xon/xoff.
- ; clc upon success (for 3.00)
- OUTCHR PROC NEAR
- push cx ; save regs
- or ah,ah ; sending a null?
- jz outch2 ; z = yes
- xor cx,cx ; clear counter
- cmp ah,flowoff ; sending xoff?
- jne outch1 ; ne = no
- mov xofsnt,false ; supress xon from chkxon buffer routine
- outch1: cmp xofrcv,true ; Are we being held?
- jne outch2 ; No - it's OK to go on
- loop outch1 ; held, try for a while
- mov xofrcv,false ; timed out, force it off and fall thru
- outch2: push dx ; Save register
- mov al,ah ; Parity routine works on AL
- call dopar ; Set parity appropriately
- ; Begin revised output routine
- ;; and al,07fh
- mov byte ptr temp,al ; put data there
- cmp prthnd,0 ; Got a handle yet?
- jne outch3 ; Yup just go on
- call opnprt ; Else 'open' the port
- outch3: push bx
- mov bx,prthnd ; port handle
- mov cx,1 ; one byte to write
- mov dx,offset temp ; place where data will be found
- mov ah,write2 ; dos 2 write to file/device
- int dos
- pop bx ; end of revised routine
- pop dx
- pop cx
- jc outch4 ; stc => failure
- clc ; clc for success
- ret
- outch4: writestring write2err
- stc
- ret
- OUTCHR ENDP
- ; This routine blanks the screen. Returns normally.
-
- CMBLNK PROC NEAR
- push ax ; save regs
- push dx
- mov ah,prstr
- mov dx,offset blank
- int dos
- pop dx
- pop ax
- ret
- CMBLNK ENDP
-
- ; Homes the cursor. Returns normally.
-
- LOCATE PROC NEAR
- mov dx,0 ; Go to top left corner of screen
- jmp poscur
- LOCATE ENDP
-
- ; Write a line at the bottom of the screen...
- ; the line is passed in dx, terminated by a $. Returns normally.
- putmod proc near
- push dx ; preserve message
- mov dx,1800H ; assume plus
- cmp bigscreen,0 ; is it a 110?
- jne putmod1 ; ne => its a plus
- mov dx,0F00H ; now address line 15
- putmod1:
- call poscur
- mov dx,offset invseq ; put into inverse video
- mov ah,prstr
- int dos
- pop dx ; get message back
- int dos ; print it
- mov dx,offset nrmseq ; normal video
- int dos
- ret
- putmod endp
-
- ; clear the mode line written by putmod. Returns normally.
- clrmod proc near
- mov dx,1800H ; plus by default
- cmp bigscreen,0 ; is it a 110?
- jne clrmod1 ; ne => it is a plus
- mov dx,0F00H
- clrmod1:
- call poscur ; Go to bottom row
- call clearl ; Clear to end of line
- ret
- clrmod endp
-
- ; Put a help message on the screen.
- ; Pass the message in ax, terminated by a null. Returns normally.
- puthlp proc near
- push dx ; save regs
- push si
- push ax ; preserve this
- mov ah,prstr
- mov dx,offset crlf
- int dos
- pop si ; point to string again
- puth0: mov ah,prstr
- mov dx,offset invseq ; put into reverse video
- int dos
- mov ah,prstr
- mov dx,offset ivlseq ; make line inverse video
- int dos
- cld
- puth1: lodsb ; get a byte
- cmp al,0 ; end of string?
- je puth2
- mov dl,al
- mov ah,conout
- int dos ; else write to screen
- cmp al,lf ; line feed?
- je puth0 ; yes, clear the next line
- jmp puth1
- puth2: mov ah,prstr
- mov dx,offset crlf
- int dos
- mov dx,offset nrmseq ; normal video
- int dos
- pop si
- pop dx
- ret
- puthlp endp
-
-
- ; Set the baud rate for the current port, based on the value
- ; in the portinfo structure. Returns carry clear.
-
- BAUDST PROC NEAR
- saveregs
- mov dx,offset bdtab ; baud rate table, ascii
- xor bx,bx ; help is the table itself
- mov ah,cmkey ; get keyword
- call comnd
- jc baudst3 ; c = failure
- push bx ; save result
- mov ah,cmeol ; get confirmation
- call comnd
- pop bx
- jc baudst3 ; c = failure
- mov si,portval
- mov ax, offset port2
- cmp ax,si ; using the modem?
- jne baudst2 ; ne => no
- cmp bigscreen,1 ; using plus?
- je baudst1 ; e => yes
- mov bx,5 ; only 300 baud legal on 110 modem
- jmp baudst2
- baudst1:cmp bx,5 ; 300 baud
- je baudst2 ; 300 baud is ok
- mov bx,7 ; if not 300, then it's 1200
- baudst2:
- mov ax,[si].baud ; remember original value
- mov [si].baud,bx ; set the baud rate
- ;; call dobaud ; use common code
- ; we set baud rate in SERINI
- mov need_to_set_baud, true ; we need to update the baud rate
-
- clc
- baudst3: restoreregs
- ret
- BAUDST ENDP
-
- ; Set the baud rate for the current port, based on the value
- ; in the portinfo structure. Returns normally.
- ; it is assumed the port is open else w_ioctl returns error
-
- DOBAUD PROC NEAR
- cmp need_to_set_baud, true ; do we need to update the baud ?
- je dobaud1 ; e=> yes, update baud rate
- clc ; success
- ret ; return if not needed
- dobaud1:saveregs
- mov bx,portval
- mov dx,[bx].baud
- mov bx,offset ourbdtab
- add bx,dx ; point to character in baud tabble
- mov dx,[bx]
- mov baudx,dl ; put into baud rate messge
- mov cx,4
- mov dx,offset baudstr ; point to message
- call w_ioctl
- mov need_to_set_baud, false ; don't need to reset baud rate
- restoreregs
- ret ; Must be set before starting Kermit
- DOBAUD ENDP
-
- ; USe hardware flow control [jan]... it is assumed the port is open
- DOFLOW PROC NEAR
- saveregs
- mov bx,portval
- mov dl,'0' ; default is no flow control
- cmp [bx].floflg,0 ; doing flow control ?
- je doflow1 ; e => no flow control
- mov dl,'2'
- doflow1:mov flo_x,dl
- mov dx, offset flo_str ; C is first character
- mov cx,3 ; 3 lettters in string
- ;; writestring flo_str
- call w_ioctl
- restoreregs
- clc ; success
- ret
- doflow endp
-
- ; Get the current baud rate from the serial card and set it
- ; in the portinfo structure for the current port. Returns normally.
- ; This is used during initialization.
-
- GETBAUD PROC NEAR
- ret ; Can't do this
- GETBAUD ENDP
-
- ; SHOW MODEM - displays status of modem lines DSR, CD, CTS, in this case
- ; it just says whether or not the port is ready for i/o.
- shomodem proc near
- mov ah,CMEOL ; get a confirm
- call comnd
- jnc shmod00 ; nc=> success
- ret ; get out if failure
- shmod00:
- cmp prthnd,0 ; Got a handle yet?
- jne shmod0 ; Yup just go on
- call opnprt ; Else 'open' the port
- shmod0: mov dx,offset msmsg1 ; say port is not ready
- mov bx,prthnd
- mov al,7 ; output status command
- mov ah,ioctl ; ask DOS to look for us
- int dos
- jc shmod1 ; c = call failed, device not ready
- or al,al
- jz shmod1 ; not ready
- mov dx,offset msmsg2 ; say port is ready
- shmod1: mov ah,prstr
- int dos
- stc
- ret ; carry set upon failure
- shomodem endp
-
- getmodem proc near
- mov al,0 ; no modem status
- ret
- getmodem endp
-
-
- ; this is not used, but is left in to aid future debugging
- printal proc near ; print the value in al
- push di
- push ax
- push bx
- push dx
- push ax
- push ax
- ; print a leading space
- mov ah,2
- mov dl,' '
- int dos
- ;
- pop ax
- and al, 0f0h ; high nibble
- shr al,1
- shr al,1
- shr al,1
- shr al,1 ; high nibble to low nibble
- mov di, offset asciitab
- xor bx, bx ; bx=0
- mov bl, al
- mov dl, [di+bx]
- mov ah,2 ; print char
- int dos ; print high nibble
- ; now the low nibble
- pop ax ; get back original char
- and al, 0fh
- mov bl,al
- mov dl, [di+bx]
- mov ah, 2
- int dos ; print low nibble
- pop dx
- pop bx
- pop ax
- pop di
- ret
- printal endp
-
- ;;end of msxhpx.h include file
- ;
- ; write cx bytes to ioctl of serial port
- ;
- W_IOCTL PROC NEAR
- cmp prthnd,0 ; port opened?
- jne w_ioctl1b ; ne => yes it is open
- writechar 'I'
- ret
- w_ioctl1b:
- push ax ; save regs
- push bx
- push cx
- mov cx,1000 ; knock at port until ready
- w_ioctla:
-
- mov ah,ioctl ; first check
- mov bx, prthnd
- mov al,7 ; check status
- int dos
- cmp al,0ffh ; ok?
- loopne w_ioctla ; try again
- cmp al,0ffh
- jne w_ioctl3 ;ne => error
- pop cx ; retrieve number to write
- mov ah, ioctl ; now do write
- mov al,3
- mov bx,prthnd
- int dos
- jnc w_ioctl2
- w_ioctl1:
- writestring w_ioctlerr ; failure
- stc ; failure
- jmp w_ioctl2
- w_ioctl3:writestring io_notready
- pop cx
- stc
- w_ioctl2:
- pop bx
- pop ax
- ret
- W_IOCTL ENDP
- ;
- ; read cx bytes from ioctl of serial port to tempbuf
- ;
- R_IOCTL PROC NEAR
- cmp prthnd,0 ; port opened?
- jne r_ioctl0 ; ne => it is open
- writechar 'R'
- ret
- r_ioctl0:
- push ax ; save regs
- push bx
- mov ah,ioctl
- mov al,2
- mov bx,prthnd
- mov dx,offset tempbuf
- int dos
- jnc r_ioctl1 ; all ok
- writestring r_ioctlerr
- r_ioctl1:
- pop bx
- pop ax
- ret
- R_IOCTL ENDP
- ;
- ; check serial port for characters and return number in al
- ;
- CHK_BUFF PROC NEAR
- push cx
- push dx
- mov dx,offset chk_msg
- mov cx,2
- call w_ioctl
- jc chk_buff1 ; failure
- mov cx,1
- call r_ioctl
- jc chk_buff1 ; failure
- mov ax,tempbuf
- pop dx
- pop cx
- ret
- chk_buff1: pop dx
- pop cx
- xor ax,ax ; no characters upon failure
- ret
- CHK_BUFF ENDP
-
-
- ; Use for DOS 2.0 and above. Check the port status. If no data, skip
- ; return. Else, read in a char and return.
- PRTCHR PROC NEAR
- cmp repflg,0 ; doing replay?
- je prtch0 ; e => not doing replay
- jmp getrepchr ; get replay character if in replay
- prtch0:
- push bx
- push cx
- push si
- cmp prthnd,0 ; got a handle
- jne prtch1 ; ne = yes
- call opnprt ; open port if not
- jc prt3x ; exit if error
- prtch1: cmp count,0 ; any chars in buffer?
- jne prtch2 ; ...yes, get one
- call chk_buff ; any chars at port?
- or al,al ; ax has characters available
- jz prtch4 ; no, go to skip return
- mov ah,0
- mov cx,ax ; read as many as are available
- ; mov cx,1 ; read one char
- mov count,cx
- mov bx,prthnd
- mov ah,readf2 ; DOS read from file/device
- mov dx,offset source
- int dos
- jc prt3x ; c = failure
- mov count,ax ; number of bytes read
- mov bufout,offset source
- prtch2: dec count
- mov si,bufout
- cld
- lodsb
- mov bufout,si
- prtch3: ;;call printal ; print character from port
- pop si
- pop cx
- pop bx
- clc
- ret ; return success
- prt3x: mov ah,prstr
- mov dx,offset erms50
- int dos
- prtch4: pop si
- pop cx
- pop bx
- stc ; stc means no characters
- ret
- PRTCHR ENDP
-
- tprn proc near
- ret
- tprn endp
-
- breakkey proc near ; handle pressing of break key
- push ax
- push ds
- mov ax,data
- mov ds,ax ; get correct data segment
- mov need_break,true ; flag that break needs setting
- pop ds
- pop ax
- iret
- breakkey endp
-
- ; Send a break out the current serial port. Returns normally.
- ; sendbrw is worker routine time in milliseconds in ax
- SENDBRW PROC NEAR
- push cx
- push dx
- push ax ; save time of break
- mov dx,offset brk_on
- mov cx,3
- call w_ioctl
- pop ax ; restore time
- call pcwait ; delay the appropriate time
- mov dx,offset brk_off
- mov cx,3
- call w_ioctl
- pop dx
- pop cx
- mov need_break,false ; don't need to do break
- sendbrw1: clc ; clear carry to stay in Connect mode
- ret
- SENDBRW ENDP
-
- SENDBR PROC NEAR ; Send a Break
- mov ax,275 ; 275 ms for normal break
- jmp sendbrw ; go to worker routine
- SENDBR ENDP
-
- SENDBL PROC NEAR ; Send a Long Break
- mov ax,1800 ; 1800 ms for long break
- jmp sendbrw ; go to worker routine
- SENDBL ENDP
-
- ; IHOSTS - Initialize the host by sending XON, or equivalent, and enter the
- ; cycle of clear input buffer, wait 1 second, test if buffer empty then exit
- ; else repeat cycle. Requires that the port be initialized before hand.
- ; Ihosts is used by the local send-file routine just after initializing
- ; the serial port.
- ; 22 March 1986 [jrd]
-
- IHOSTS PROC NEAR
- push ax ; save the registers
- push bx
- push cx
- push dx
- mov bx,portval ; port indicator
- mov ax,[bx].flowc ; put Go-ahead flow control char in ah
- or ah,ah ; don't send null if flow = none
- jz ihosts1 ; z = null
- call outchr ; send it (release Host's output queue)
- nop ; outchr can do skip return
- nop
- nop
- ihosts1:call clrbuf ; clear out interrupt buffer
- pop dx ; empty buffer. we are done here
- pop cx
- pop bx
- pop ax
- ret
- IHOSTS ENDP
-
- ; IHOSTR - initialize the remote host for our reception of a file by
- ; sending the flow-on character (XON typically) to release any held
- ; data. Called by receive-file code just after initializing the serial
- ; port. 22 March 1986 [jrd]
- IHOSTR PROC NEAR
- push ax ; save regs
- push bx
- push cx
- mov bx,portval ; port indicator
- mov ax,[bx].flowc ; put Go-ahead flow control char in ah
- or ah,ah ; don't send null if flow = none
- jz ihostr1 ; z = null
- call outchr ; send it (release Host's output queue)
- nop ; outchr can do skip return
- nop
- nop
- ihostr1:pop cx
- pop bx
- pop ax
- ret
- IHOSTR ENDP
-
- DTRLOW PROC NEAR ; Global proc to Hangup the Phone by making
- ; DTR and RTS low.
- mov ah,CMLINE ; allow text to be able to display help
- mov bx,offset rdbuf ; dummy buffer
- mov dx,offset hnghlp ; help message
- call comnd ; get a confirm
- jnc dtrlow1 ; nc => success
- ret ; get out if failure
- dtrlow1:
- call serhng ; drop DTR and RTS
- mov ah,prstr ; give a nice message
- mov dx,offset hngmsg
- int dos
- clc ; carry clear for success
- ret
- DTRLOW ENDP
-
- ; Hang up the Phone. Similar to SERRST except it just forces DTR and RTS low
- ; to terminate the connection. 29 March 1986 [jrd]
- ; Calling this twice without intervening calls to serini should be harmless.
- ; Returns normally.
- ; Adapted from recommendation by Mike Mellinger. [jrd]
- SERHNG PROC NEAR
- saveregs
- cmp prthnd,0 ; is the port open
- je serhn1 ; e => it is closed
- ; mov ax,offset port3
- ; cmp ax,portval
- ; je serhn4 ; don't do anything for 82164A
- cmp bigscreen,1 ; do we have the plus?
- je serhn2 ; yes we do
- mov dx,offset $off_m110 ; separate hangup for 110
- mov cx,len$off_m110
- jmp serhn3
- serhn2:
- mov dx,offset $off_m ; magic words to turn off DTR
- mov cx,off_len ; their length
- serhn3:
- call w_ioctl ; write them
- serhn4: mov bx,prthnd ; close port
- mov ah,close2 ; close the device
- int dos
- mov prthnd,0 ; port no longer open
- mov ax,1000
- call pcwait ; delay so hangup can work
- serhn1:
- restoreregs
- ret
- SERHNG ENDP
-
- ; Wait for the # of milliseconds in ax, for non-IBM compatibles.
- ; Thanks to Bernie Eiben for this one.
- pcwait proc near
- mov cx,240 ; inner loop counter for 1 millisecond
- pcwai1: sub cx,1 ; inner loop takes 20 clock cycles
- jnz pcwai1
- dec ax ; outer loop counter
- jnz pcwait ; wait another millisecond
- ret
- pcwait endp
-
-
- ; Position the cursor according to contents of DX:
- ; DH contains row, DL contains column. Returns normally.
- POSCUR PROC NEAR
- push ax ; save regs
- push dx
- push di
- mov ax,ds
- mov es,ax ; address data segment!!
- cld
- mov di,offset colno
- mov al,dl ; column
- call nout
- mov al,'x'
- stosb
- mov al,dh ; row
- call nout
- mov al,'Y'
- stosb
- mov al,'$'
- stosb
- mov dx,offset movcur
- mov ah,prstr
- int dos ; print the sequence
- pop di
- pop dx
- pop ax
- ret
- POSCUR ENDP
-
- NOUT PROC NEAR
- cbw ; extend the word
- div byte ptr ten ; divide by ten
- or al,al ; any quotient?
- jz nout1 ; no, forget this
- push ax ; save current result
- call nout ; output high order
- pop ax ; restore
- nout1: mov al,ah ; get digit
- add al,'0' ; make printable
- stosb ; put in buffer
- ret ; and return
- NOUT ENDP
-
- ; Delete a character from the terminal. This works by printing
- ; backspaces and spaces. Returns normally.
-
- DODEL PROC NEAR
- push ax ; save regs
- push dx
- mov ah,prstr
- mov dx,offset delstr ; Erase weird character
- int dos
- pop dx
- pop ax
- ret
- DODEL ENDP
-
- ; Move the cursor to the left margin, then clear to end of line.
- ; Returns normally.
-
- CTLU PROC NEAR
- push ax ; save regs
- push dx
- mov ah,prstr
- mov dx,offset clrlin
- int dos
- call clearl
- pop dx
- pop ax
- ret
- CTLU ENDP
-
- ; Set the current port.
-
- COMS PROC NEAR
- mov dx,offset comptab ; table of comms ports
- mov bx,0 ; use keywords as help
- mov ah,cmkey ; parse a keyword
- call comnd
- jnc coms1 ; nc => success
- ret ; get out if failure
- coms1: push bx
- mov ah,CMEOL
- call comnd ; Get a confirm
- jc comx ; carry => failure
-
- call serr_x ; force close on serial port
-
- pop bx
- mov flags.comflg,bl ; Set the comm port flag
- cmp flags.comflg,1 ; Using Com 1?
- jne coms2 ; ne = no
- mov portval,offset port1
- clc ; carry clear for success
- ret
- coms2: cmp bl,2 ; using com2?
- jne coms3 ; ne = no
- mov portval,offset port2
- clc ; success [jan]
- ret
- coms3:
- mov portval,offset port3
- clc ; success [jan]
- ret
- comx: pop bx
- stc ; carry set for failure [jan]
- ret
- COMS ENDP
-
- ; Set tektronix emulation on/off
-
- VTS PROC NEAR
- mov dx,offset termtb
- mov bx,0
- mov ah,cmkey
- call comnd
- jnc vts00 ; nc => success
- ret ; return if failure
- vts00: push bx
- mov ah,CMEOL
- call comnd ; Get a confirm
- jc vtx ; carry => didn't get a confirm
- pop bx
- cmp bl,hpkeynum ; want hpkeyboard
- jne vts0 ; ne => no
- mov keyflg,hpkeynum
- call setkeyboard
- clc
- ret
- vts0: cmp bl,altkeynum ; want alt keyboard?
- jne vts0a ; ne=> no
- mov keyflg,altkeynum ; turn on altkeyboard
- call setkeyboard
- clc
- ret
- vts0a: cmp bl, tekonnum ; enable tek ?
- jne vts0b ; ne => don't enable
- and denyflg, not tekxflg ; clear tekxflgbit
- mov tekbyte, bl ; for status display
- clc
- ret
- vts0b: cmp bl, tekoffnum ; disable tek ?
- jne vts1 ; ne=> don't disable
- or denyflg, tekxflg ; set deny tek bit
- mov tekbyte, bl ; for status
- clc
- ret
- vts1:
- mov flags.vtflg,bl ; Set the Tektronix emulation flag [jan]
- mov tekflg,0 ;need to re-initialize tek emulator [jan]
- clc ; success
- ret
- vtx: pop bx
- stc ; carry set => failure
- ret
- VTS ENDP
-
- VTSTAT PROC NEAR ; For Status display [jrd]
- mov bx,offset vtstbl ; table of things to show
- jmp statc ; common status code
- ;; ret ; no emulator status to display
- VTSTAT ENDP
-
- ; Save the screen to a buffer and then append buffer to a disk file. [jrd]
- ; Default filename is Kermit.scn; actual file can be a device too. Filename
- ; is determined by mssset and is passed as pointer dmpname.
-
- DUMPSCR PROC NEAR ; Dumps screen contents to a file. Just Beeps here
- call beep
- ret
- DUMPSCR ENDP
-
-
- ; Initialize variables to values used by the generic MS DOS version.
- lclose proc near
- call sethpkey ; turn on hp keyboard
- ret
- lclose endp
-
- lpop proc near ; executed when returing from dos
- call setkeyboard ; turn on the appropriate keyboard
- ret
- lpop endp
-
- lpush proc near ; call before pushing to dos
- call sethpkey ; turn on hp keyboard
- ret
- lpush endp
-
- lclini proc near
- saveregs
- mov dosnum,200h ; force dosnum to 2.00 so replay proc works
- mov prtrdy,true ; port is ready
- call msuinit ; init keyboard translator
- mov lclexit, offset lclose ; let mssker know that lclose exists
- mov lclsusp, offset lpush ; for mssker (optional)
- mov lclrest, offset lpop
- mov flags.vtflg,0 ; Don't do terminal emulation
- ;; mov prthnd,0 ; no port handle yet. [jrd]
- ;; call opnprt ; Get file handle for comm port
- ;; mov portval, offset port2
- ;; mov flags.comflg,2 ; modem on at startup
- mov portval, offset port1
- mov flags.comflg, 1 ; serial port is default at startup
- call setkeyboard ; turn on keyboard
- call id_terminal ; do we have 110 or portable plus?
- cmp bigscreen,1 ; using a plus
- je lclini1 ; e=> yes we are
- mov bx,offset port2
- mov [bx].baud,5 ; modem on 110 = 300 baud
-
- lclini1:
- call scrsavinit ; initialize memory for screen save
- writestring alpha_disp ; turn on the alpha display
- call savescr ; save an alpha screen to initialize
- writestring helpini
- restoreregs
- clc
- ret
-
- lclini endp
-
- ; Get a file handle for the communications port. Use DOS call to get the
- ; next available handle. If it fails, ask user what value to use (there
- ; should be a predefined handle for the port, generally 3). The open
- ; will fail if the system uses names other than "COM1", "COM2", "COM3","AUX".
- opnprt proc near
- call serr_x ; close port if already open
- mov ax, portval
- cmp ax, offset port1
- jne opnprt0
- mov flags.comflg,1
- jmp opnprt0d ; proceed with the open
- opnprt0:
- mov ax, portval
- cmp ax, offset port2
- jne opnprt0a
- mov flags.comflg,2
- jmp opnprt0d ; proceed with the open
- opnprt0a:
- mov ax, portval
- cmp ax, offset port3
- jne opnprt0b
- mov flags.comflg,3
- jmp opnprt0d ; proceed with the open
- opnprt0b: mov portval, offset port1 ; if all else fails
- mov flags.comflg, 1
-
- opnprt0d:
- mov al,flags.comflg
-
-
- dec al ; flags.comflg = 1 for com1, 2 com2, 3 com3
- mov ah,0
- mov si,ax
- shl si,1 ; double index
- mov dx,prttab[si]
- mov ah,open2
- mov al,2
- int dos
- jnc opnpr1
- mov ah,prstr ; It didn't like the string
- mov dx,offset erms41
- int dos
- mov prthnd,0 ; clear port file handle
- stc ; carry set for failure
- ret
- opnpr1: mov prthnd,ax ; Call succeeded
- mov ah,ioctl
- mov al,00h ; get device info
- xor dx,dx
- xor cx,cx ; 0 bytes to read/write
- mov bx,prthnd ; port's handle
- int dos
- or dl,20h ; set binary mode in device info
- xor cx,cx ; 0 bytes to read/write
- mov dh,0
- mov ah,ioctl
- mov al,01h ; set device info
- int dos
- mov ax,portval
- cmp ax,offset port3 ; using 82164A
- jne opnpr2
- clc ; don't need to write to 82164a
- ret
- opnpr2:
- cmp ax,offset port1 ; using port1 (serial) ?
- jne opnpr3 ; ne => no, not using port 1
- mov dx,offset $m1
- mov cx,len_$m1
- call w_ioctl
- clc
- ret
- opnpr3: cmp ax, offset port2 ; using modem
- jne opnpr4 ; ne => not using modem
- mov dx,offset $m0
- mov cx,len_$m0
- call w_ioctl
- clc
- ret
-
- opnpr4: clc
- ret ; carry clear for success
- opnprt endp
-
- ; set the interrupt vectors
-
- setints proc near
- ; save break vector and set to breakkey
- ; first save the break existing interrupt
- cmp ints_set,true ; interrupt vectors set?
- je setints1 ; je=>yes, don't reset!
- push ax
- push bx
- push dx
- push es
- mov al, brk_int
- mov ah,35h ; get interrupt vector
- int dos ; es:bx has long pointer
- mov savbrko,bx ; offset of routine
- mov savbrks,es ; segment
- pop es
- ; now set the break interrupt
- push ds
- mov dx,offset breakkey ; address of interrupt routine
- push cs ; segment of breakkey is code
- pop ds ; ds=cs
- mov ah,25h ; set vector call
- mov al,brk_int ; break key interrupt
- int 21h ; set the vector
- pop ds ; restore data segment
- ; end of setting break vector
- setints1:
- mov ints_set,true ; we have set the interrupts
- pop dx
- pop bx
- pop ax
- clc
- ret
- setints endp
-
- restoreints proc near ; restore interrupts
- cmp ints_set,false ; have we set interrupts?
- je restoreints1 ; don't restore if not set!
-
- ; resotore break key interrupt
- push ds
- mov dx,savbrko ; original offset
- mov ax,savbrks ; original segment
- mov ds,ax ; original segment to ds
- mov ah,25h ;
- mov al,brk_int
- int dos ; restore original interrupt
- pop ds
- ;;end of restore
-
-
- restoreints1: mov ints_set,false
- clc
- ret
- restoreints endp
-
-
-
- ; Initialization for using serial port. Returns normally.
- SERINI PROC NEAR
- cld ; Do increments in string operations
- cmp prthnd,0 ; Got Handle already?
- jne ser_x ; ne = yes, skip open
- ;; call setints ; set interrupt vectors
- call opnprt ; open handle
- jc serin2 ; carry set = failure
-
- ser_x:
- call dobaud ; set baud rate
- jc serin2
- call doflow ; set hardware flow control
- jc serin2
- push bx
- mov bx,portval ; get port
- mov parmsk,0ffh ; parity mask, assume parity is None
- cmp [bx].parflg,parnon ; is it None?
- je serin1 ; e = yes
- mov parmsk,07fh ; no, pass lower 7 bits as data
- serin1: mov bx,[bx].flowc ; get flow control chars
- mov flowoff,bl ; xoff or null
- mov flowon,bh ; xon or null
- pop bx
-
- clc ; carry clear for success
- ret
- serin2: writestring serierr ; error message
-
- call serr_x ; force close on bad port
- stc
- ret
- SERINI ENDP
-
-
- ; Reset the serial port. This is the opposite of serini. Calling
- ; this twice without intervening calls to serini should be harmless.
- ; Returns normally.
-
- SERRST PROC NEAR
- cmp flags.extflg,0
- jne serr_x
- ret
- serr_x: call serhng ; close files and hangup
- ;; mov need_to_set_flow, true ; need to update flow control
- mov need_to_set_baud, true ; need to update baud rate
- ret
- SERRST ENDP
-
- ; Produce a short beep. The PC DOS bell is long enough to cause a loss
- ; of data at the port. Returns normally.
-
- BEEP PROC NEAR
- mov dl,bell
- mov ah,dconio
- int dos
- ret
- BEEP ENDP
-
- ; Dumb terminal emulator. Doesn't work too well above 1200 baud (and
- ; even at 1200 baud you sometimes lose the first one or two characters
- ; on a line). Does capture (logging), local echo, debug display, tests
- ; for printer/logging device not ready. 27 Sept 86 [jrd].
- term proc near
- saveregs
-
- mov argadr,ax ; save argument ptr
- mov si,ax ; this is source
- mov di,offset ourarg ; place to store arguments
- push es ; save register
- push ds
- pop es ; set es to data segment
- mov cx,size termarg
- cld
- rep movsb ; copy into our arg blk
- pop es ; restore reg
- and ourarg.flgs,not (prtscr) ; no screen printing at startup
- mov ax,ourarg.captr
- mov captrtn,ax ; buffer capture routine
- call setints ; set interrupts for connect mode
- term0a:
- cmp flags.vtflg,tttek ; tek emulation on?
- jne term0
- call tekini
- term0:
- call restscr ; restore the screen
- mov parmsk,0ffh ; parity mask, assume parity = None
- cmp ourarg.parity,parnon ; is parity None?
- je term1 ; e = yes, keep all 8 bits
- mov parmsk,07fh ; else keep lower 7 bits
-
- term1:
- cmp prtrdy,false ; ready to read port?
- je term5 ; get out
- call portchr ; read char from serial port
- jnc short term3 ; nc = no char, go on
- cmp flags.vtflg,tttek ; doing tek emulation?
- je term1a ;e=yes, already doing tek
- call stringchek ; check for special escape strings
- jnc short term3 ; nc => don't display
- term1a: call outtty ; display and capture char [jrd]
- term3:
- inc keydelay ;just check keyboard once
- mov ax,keydelay ;each eight reads of the port
- and ax,7 ;should speed things up
- jnz term1 ;at higher baud rates [jan]
- cmp need_break,false ; do we need to send a break?
- je term3a ;e=> no, get next key
- call sendbr ; do the required break
- term3a:
- call keybd ; call keyboard xlator, send results
- jnc term1 ; nc = stay in Connect mode
- term5: ; [gaw@prc]
- call savescr ; save screen [gaw@prc]
- cmp flags.vtflg,tttek
- jne term6 ; skip string write if not in tek
- writestring alpha_disp ; turn on alpha display for kermit
- term6:
- cmp prtrdy, true ; need to set kbdflg if wierd exit
- je term7
- mov kbdflg,'C' ; so we exit connect mode
- mov prtrdy,true
- term7:
- call restoreints ; restore connect mode interrupts
- restoreregs
- ret ; and return to caller
- term endp
-
-
- termtog proc near ; toggle terminal type [jan]
- call savescr ; save present screen
- cmp flags.vtflg,tttek ; doing tek emulation ?
- jne termtog1 ; ne means doing tek
- writestring alpha_disp
- mov flags.vtflg,ttgenrc ; turn on alpha display
- call restscr ; restore previous alpha display
- clc
- ret
- termtog1:
- mov flags.vtflg,tttek ; turn on tek display
- call tekini
- call restscr ; restore the previous screen
- clc ; do not exit Connect mode [jrd]
- ret ; stay in connect mode
- termtog endp
-
- kclrscn proc near ; clear screen in text or Tek mode [jrd]
- cmp flags.vtflg,tttek ; doing Tek emulation?
- jne kclrsc1 ; ne = no
- call tekcls ; blank and some more
- clc ; stay in Connect mode
- ret
- kclrsc1:call cmblnk ; blank screen
- clc ; stay in Connect mode
- ret
- kclrscn endp
-
- getflgs proc near
- mov al,ourarg.flgs ;supply flags for msggri [jan]
- ret
- getflgs endp
-
- ; put the character in al to the screen, do capture and printing,
- ; does translation for Set Input command.
- ; Adapted from msyibm.asm [jrd]
- outtty proc near
- cmp flags.vtflg,tttek ; doing tektronix emulation?
- jne outtty1 ; ne= not doing tek emulation
- jmp tekemu ; do tekemu and return
- outtty1:
- ;; call printal ; debug
- test flags.remflg,d8bit ; keep 8 bits for displays?
- jnz outnp8 ; nz = yes, 8 bits if possible
- and al,7fh ; remove high bit
- outnp8: cmp rxtable+256,0 ; is translation off?
- je outnp7 ; e = yes, off
- push bx ; Translate incoming char [jrd]
- mov bx,offset rxtable ; address of translate table [jrd]
- xlatb ; new char is in al
- pop bx
- outnp7:
- test ourarg.flgs,capt ; capturing output? Can be shut off
- jz outnoc ; no, forget this part
- push ax ; save char
- call captrtn ; give it captured character
- pop ax ; restore character and keep going
- outnoc: test ourarg.flgs,prtscr ; should we be printing?
- jz outnop ; no, keep going
- push ax
- mov ah,print_out ; write to system printer device
- mov dl,al
- int dos
- pop ax
- jnc outnop ; nc = successful print
- push ax
- call beep ; else make a noise and
- call trnprs ; turn off printing
- pop ax
- outnop: cmp flags.vtflg,0 ; emulating a terminal?
- jnz outnop1 ; nz = yup, go do something smart
- test ourarg.flgs,trnctl ; debug? if so use dos tty mode
- jz outnp5 ; z = no
- mov ah,conout
- cmp al,7fh ; Ascii Del char or greater?
- jb outnp1 ; b = no
- je outnp0 ; e = Del char
- push ax ; save the char
- mov dl,7eh ; output a tilde for 8th bit
- int dos
- pop ax ; restore char
- and al,7fh ; strip high bit
- outnp0: cmp al,7fh ; is char now a DEL?
- jne outnp1 ; ne = no
- and al,3fH ; strip next highest bit (Del --> '?')
- jmp outnp2 ; send, preceded by caret
- outnp1: cmp al,' ' ; control char?
- jae outnp3 ; ae = no
- add al,'A'-1 ; make visible
- outnp2: push ax ; save char
- mov dl,5eh ; caret
- int dos ; display it
- pop ax ; recover the non-printable char
- outnp3: mov dl,al
- int dos
- ret
- ;outnp4: ;cmp al,bell ; bell (Control G)? [jrd]
- ;jne outnp5 ; ne = no
- ; jmp beep ; use short beep, avoid char loss.
- outnop1:
- outnp5:
- cmp bigscreen, 1 ; do we have the plus
- jne outnp5a ; ne => we just have a 110
- cmp al,14 ; is the character CTRL N?
- je outnp6 ; e=> yes, do not print CTRL N
- ; (CTRL N on Plus messes up character
- ; set)
- push si ; print character on plus
- mov plus_char,al ; where si expects it
- mov bx,6 ; don't know why
- mov si,offset plus_char ; write the character
- int 50h ; special interrupt
- pop si
- ret
-
- outnp5a:
- mov ah,conout ; dostty screen mode
- mov dl,al ; write without intervention.
- int dos ; else let dos display char
- outnp6: ret ; and return
- outtty endp
-
-
-
- ; send the character in al out to the serial port; handle echoing.
- ; Can send an 8 bit char while displaying only 7 bits locally.
- outprt proc near
- test ourarg.flgs,lclecho ; echoing?
- jz outpr1 ; z = no, forget it
- push ax ; save char
- call outtty ; print it
- pop ax ; restore
- outpr1: mov ah,al ; this is where outchr expects it
- call outchr ; output to the port
- ret
- outprt endp
-
- ; Get a char from the serial port manager
- ; returns with carry on if a character is available
- portchr proc near
- call prtchr ; character at port?
- jnc portc1
- portc0: clc ; no carry -> no character
- ret ; and return
- portc1: and al,parmsk ; apply 8/7 bit parity mask
- ; don't catch anybody [jan]
- ; or al,al ; catch nulls
- ; jz portc0 ; z = null, ignore it
- ; cmp al,del ; catch dels
- ; je portc0 ; e = del, ignore it
- stc ; have a character
- ret ; and return
- portchr endp
-
- ;; keyboard translator action routines, system dependent, called from msugen.
- ; These are invoked by a jump instruction. Return carry clear for normal
- ; processing, return carry set to exit Connect mode (kbdflg has transfer char)
-
- ; msu calls this to send keystroke out the port
- chrout proc near
- cmp repflg,0 ; in replay mode?
- je chrout1 ; e=> not doing replay
- jmp repchrout ; display the replay character
- chrout1:call outprt ; put char in al to serial port
- clc ; stay in Connect mode
- ret
- chrout endp
-
- trnprs: push ax ; toggle Copy screen to printer
- test ourarg.flgs,prtscr ; are we currently printing?
- jnz trnpr2 ; nz = yes, its on and going off
- mov ah,ioctl
- mov al,7 ; get output status of printer
- push bx
- mov bx,4 ; file handle for system printer
- int dos
- pop bx
- jc trnpr1 ; c = printer not ready
- cmp al,0ffh ; Ready status?
- je trnpr2 ; e = Ready
- trnpr1: call beep ; Not Ready, complain
- jmp trnpr3 ; and ignore request
- trnpr2: xor ourarg.flgs,prtscr ; flip the flag
- trnpr3: pop ax
- clc
- ret
-
- klogon proc near ; resume logging (if any)
- test flags.capflg,logses ; session logging enabled?
- jz klogn ; z = no, forget it
- or ourarg.flgs,capt ; turn on capture flag
- push bx
- mov bx, argadr ; update kermits capture flag
- or [bx].flgs, capt
- pop bx
- klogn: clc
- ret
- klogon endp
-
- klogof proc near ; suspend logging (if any)
- and ourarg.flgs,not capt ; stop capturing
- push bx
- mov bx, argadr
- and [bx].flgs, not capt ; update kermits capture flag
- pop bx
-
- klogo: clc
- ret
- klogof endp
-
- snull: mov ah,0 ; send a null
- call outchr ; send without echo or logging
- clc
- ret
-
- kdos: mov al,'P' ; Push to DOS
- jmp short cmdcom
- cstatus:mov al,'S' ; these commands exit Connect mode
- jmp short cmdcom
- cquit: mov al,'C'
- jmp short cmdcom
- cquery: mov al,'?'
- jmp short cmdcom
- cmdcom: mov kbdflg,al ; pass char to msster.asm via kbdflg
- stc ; say exit Connect mode
- ret
-
- ; Jumping here is the same as a ret.
-
- R PROC NEAR
- ret
- R ENDP
-
- code ends
- end
-